package com.mallcai.bigdata.ladon.service.report.impl;

import com.cake.bigdata.starter.exception.category.BusinessException;
import com.mallcai.bigdata.ladon.config.ApplicationContextProvider;
import com.mallcai.bigdata.ladon.dpl.entity.report.*;
import com.mallcai.bigdata.ladon.dpl.entity.system.RoleRlReport;
import com.mallcai.bigdata.ladon.dpl.mapper.report.*;
import com.mallcai.bigdata.ladon.dpl.mapper.system.RoleRlReportMapper;
import com.mallcai.bigdata.ladon.dpl.vo.QueryFieldType;
import com.mallcai.bigdata.ladon.service.report.IGroupService;
import com.mallcai.bigdata.ladon.service.report.IReportService;
import com.mallcai.bigdata.ladon.service.system.IAccountService;
import com.mallcai.bigdata.ladon.tools.CodeBuilderTool;
import com.mallcai.bigdata.ladon.vo.Pair;
import com.mallcai.bigdata.ladon.vo.args.QueryArg;
import com.mallcai.bigdata.ladon.vo.args.component.BaseComponent;
import com.mallcai.bigdata.ladon.vo.args.component.ComponentFactory;
import com.mallcai.bigdata.ladon.vo.args.component.SelectComponent;
import com.mallcai.bigdata.ladon.vo.system.MenuVo;
import com.mallcai.bigdata.ladon.vo.system.TreeNodeVo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.util.Assert;

import java.util.*;

/**
 * Created by oneape<oneape15@163.com>
 * Created 2019-07-09 17:03.
 * Modify:
 */
@Slf4j
@Service
public class ReportService implements IReportService {
    @Autowired
    private IGroupService       iGroupService;
    @Autowired
    private ReportMapper        reportMapper;
    @Autowired
    private ReportRlGroupMapper reportRlGroupMapper;
    @Autowired
    private RoleRlReportMapper  roleRlReportMapper;
    @Autowired
    private QueryFieldMapper    queryFieldMapper;
    @Autowired
    private ReportColumnMapper  reportColumnMapper;
    @Autowired
    private ReportSqlMapper     reportSqlMapper;
    @Autowired
    private IAccountService     accountService;
    @Autowired
    private GroupMapper         groupMapper;


    /**
     * 添加
     *
     * @param report   Report
     * @param groupIds List 所属报表组
     * @return int
     */
    @Transactional
    @Override
    public int addReport(Report report, List<Long> groupIds) {
        Assert.isTrue(StringUtils.isNotBlank(report.getName()), "报表名称为空");
        if (reportMapper.hasSameName(groupIds, report.getName(), null) > 0) {
            throw new BusinessException("报表名称已存在");
        }
        if (1 == report.getAutoCreatedCode()) {
            report.setCode(CodeBuilderTool.randomStr(CODE_LEN));
        } else {
            if (StringUtils.isBlank(report.getCode())) {
                throw new BusinessException("报表编码不能为空");
            }
            if (reportMapper.hasSameCode(groupIds, report.getCode(), null) > 0) {
                throw new BusinessException("报表编码已存在");
            }
        }
        int status = reportMapper.insert(report);
        if (status > 0) {
            // 耗时处理,循环插入报表与报表关系
            groupIds.forEach(gId -> reportRlGroupMapper.insert(new ReportRlGroup(gId, report.getId())));
        }
        return status;
    }

    /**
     * 修改
     *
     * @param report   Report
     * @param groupIds List 所属报表组
     * @return int
     */
    @Transactional
    @Override
    public int editReport(Report report, List<Long> groupIds) {
        Assert.isTrue(StringUtils.isNotBlank(report.getName()), "报表名称为空");
        Assert.isTrue(report.getId() != null, "报表主键为空");
        accountService.checkPermission(reportMapper.findById(report.getId()).getOwner());

        if (reportMapper.hasSameName(groupIds, report.getName(), report.getId()) > 0) {
            throw new BusinessException("报表名称已存在");
        }
        if (0 == report.getAutoCreatedCode()) {
            if (StringUtils.isBlank(report.getCode())) {
                throw new BusinessException("报表编码不能为空");
            }
            if (reportMapper.hasSameCode(groupIds, report.getCode(), report.getId()) > 0) {
                throw new BusinessException("报表编码已存在");
            }
        }
        int status = reportMapper.update(report);
        if (status > 0) {
            // 删除旧关系
            reportRlGroupMapper.delByReportId(report.getId());
            // 耗时处理,循环插入报表与报表关系
            groupIds.forEach(gId -> reportRlGroupMapper.insert(new ReportRlGroup(gId, report.getId())));
            ApplicationContextProvider.publishEvent(MetaRefreshEvent.newReportChangeEvent(report.getCode()));
        }
        return status;
    }

    /**
     * 删除
     *
     * @param report Report
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int delReport(Report report) {
        Report tmp = reportMapper.findById(report.getId());
        if (tmp == null) {
            return 0; // 不存在的报表
        }
        accountService.checkPermission(tmp.getOwner());

        // 判断报表是否已经分配给用户角色,如果存在则不能被删除
        List<RoleRlReport> rlRoles = roleRlReportMapper.getByReportId(report.getId());
        if (rlRoles != null && rlRoles.size() > 0) {
            StringBuilder roleNames = new StringBuilder();
            rlRoles.forEach(r -> roleNames.append(r.getRoleName()).append(","));
            throw new BusinessException("报表正在被角色【" + roleNames + "】使用中, 不能被删除");
        }
        int status = reportMapper.delete(report);
        if (status > 0) {
            // 删除旧关系
            reportRlGroupMapper.delByReportId(report.getId());
            // 删除报表查询参数
            queryFieldMapper.delByReportId(report.getId());
            // 删除报表SQL信息
            List<Long> ids = new ArrayList<>();
            if (tmp.getDetailSqlId() != null) {
                ids.add(tmp.getDetailSqlId());
            }
            if (tmp.getCountSqlId() != null) {
                ids.add(tmp.getCountSqlId());
            }
            if (CollectionUtils.isNotEmpty(ids)) {
                reportSqlMapper.delByIds(ids);
            }
            // 删除报表字段信息
            reportColumnMapper.delByReportId(report.getId());
            ApplicationContextProvider.publishEvent(MetaRefreshEvent.newReportChangeEvent(report.getCode()));
        }
        return status;
    }

    /**
     * 根据Id获取
     *
     * @param reportId Long
     * @return Report
     */
    @Override
    public Report getById(Long reportId) {
        return reportMapper.findById(reportId);
    }

    /**
     * 根据条件查询报表
     *
     * @param params Map
     * @return List
     */
    @Override
    public List<Report> getByParams(Map<String, Object> params) {
        return reportMapper.getByParams(params);
    }

    @Override
    public int saveReportSql(Long reportId, ReportSql reportSql) {
        return saveReportSql(reportId, reportSql, true);
    }

    /**
     * 保存报表查询SQL
     *
     * @param reportId  Long
     * @param reportSql ReportSql
     * @param needCheck 是否需要检查权限
     * @return int
     */
    @Transactional
    protected int saveReportSql(Long reportId, ReportSql reportSql, boolean needCheck) {
        Report report = getById(reportId);
        // 检测
        checkPermission(reportId, needCheck);

        int status;
        if (reportSql.getId() == null || reportSqlMapper.findById(reportSql.getId()) == null) {
            status = reportSqlMapper.insert(reportSql);

            // 更新报表sqlId
            if (status > 0) {
                report.setDetailSqlId(reportSql.getId());
                reportMapper.update(report);
                ApplicationContextProvider.publishEvent(MetaRefreshEvent.newReportChangeEvent(report.getCode()));
            }
        } else {
            status = reportSqlMapper.update(reportSql);
        }
        if(status > 0 && reportSql.getId() != null){
            ApplicationContextProvider.publishEvent(MetaRefreshEvent.newReportSqlChangeEvent(reportSql.getId()));
        }
        return status;
    }

    /**
     * 根据SQL主键获取详细信息
     *
     * @param sqlId Long
     * @return ReportSql
     */
    @Override
    public ReportSql getSqlInfoById(Long sqlId) {
        return reportSqlMapper.findById(sqlId);
    }

    /**
     * 保存查询参数
     *
     * @param reportId  Long
     * @param fields    List
     * @param needCheck 是否需要检查权限
     * @return int
     */
    private int saveQueryFields(Long reportId, List<QueryField> fields, boolean needCheck) {
        // 检测
        checkPermission(reportId, needCheck);

        queryFieldMapper.delByReportId(reportId);
        if (fields == null || fields.size() == 0) {
            return 1;
        }
        for (QueryField f : fields) {
            f.setReportId(reportId);
            f.setType(QueryFieldType.merge(f.getTypes()));
            boolean isLov = QueryFieldType.contains(f.getType(), QueryFieldType.LOV);
            if (!isLov) {
                f.setLovReportId(0L);
                f.setDependOn(null);
            }
            // 字段是否必填
            if (f.getMustFillIn() == null) {
                f.setMustFillIn(0);
            }
            queryFieldMapper.insert(f);
        }
        return 1;
    }

    /**
     * 保存查询参数
     *
     * @param reportId Long
     * @param fields   List
     * @return int
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int saveQueryFields(Long reportId, List<QueryField> fields) {
        int status =  saveQueryFields(reportId, fields, true);
        ApplicationContextProvider.publishEvent(MetaRefreshEvent.newReportFieldChangeEvent(reportId));
        return status;
    }

    /**
     * 获取查询参数
     *
     * @param reportId Long
     * @return List
     */
    @Override
    public List<QueryField> getQueryFields(Long reportId) {
        Report report = getById(reportId);
        if (report == null) {
            throw new BusinessException("报表信息不存在");
        }
        return queryFieldMapper.getByReportId(reportId);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public int saveReportColumns(Long reportId, List<ReportColumn> columns) {
        int status = saveReportColumns(reportId, columns, true);
        ApplicationContextProvider.publishEvent(MetaRefreshEvent.newReportColumnChangeEvent(reportId));
        return status;
    }


    private void checkPermission(Long reportId, boolean needCheck) {
        Report report = getById(reportId);
        if (report == null) {
            throw new BusinessException("报表信息不存在");
        }
        if (needCheck) {
            accountService.checkPermission(report.getOwner());
        }
    }

    /**
     * 保存报表字段列表
     *
     * @param reportId  Long
     * @param columns   List
     * @param needCheck 是否需要检查权限
     * @return int
     */
    @Transactional
    protected int saveReportColumns(Long reportId, List<ReportColumn> columns, boolean needCheck) {
        // 检测
        checkPermission(reportId, needCheck);

        reportColumnMapper.delByReportId(reportId);
        if (columns != null && columns.size() > 0) {
            columns.forEach(c -> {
                c.setReportId(reportId);
                if (c.getDrill() == null || c.getDrill() == 0) {
                    c.setDrillParams(null);
                    c.setDrillReportId(null);
                }
                if (c.getSplit() == null || c.getSplit() == 0) {
                    c.setSplitChar(null);
                    c.setSplitKvChar(null);
                }
                reportColumnMapper.insert(c);
            });
        }
        return 1;
    }

    /**
     * 获取报表参数列表
     *
     * @param reportId Long
     * @return List
     */
    @Override
    public List<ReportColumn> getReportColumns(Long reportId) {
        Report report = getById(reportId);
        if (report == null) {
            throw new BusinessException("报表信息不存在");
        }

        return reportColumnMapper.getByReportId(reportId);
    }

    @Override
    public Long getIdByCode(String code) {
        Report ans = reportMapper.findByCode(code);
        return ans != null ? ans.getId() : null;
    }

    /**
     * 根据id获取code
     *
     * @param id 报表Id
     * @return String 报表Code
     */
    @Override
    public String getCodeById(Long id) {
        Report report = reportMapper.findById(id);
        return report != null ? report.getCode() : null;
    }

    /**
     * 获取报表树
     *
     * @param simpleReport null - 查询所有; 0 - 普通报表; 1 - 简单的报表(LOV);
     * @param filterIds    List 过滤掉的报表Id
     * @param fixOption    String 携带特定值, NULL, ALL
     * @return List
     */
    @Override
    public List<TreeNodeVo> getReportTree(Integer simpleReport, List<Long> filterIds, String fixOption) {
        List<TreeNodeVo> allNodes = new ArrayList<>();

        // 获取所有报表组信息
        List<Group> groups = iGroupService.getAllSimpleGroup();

        if (groups != null && groups.size() >= 0) {

            Pair<Integer, Map<Integer, List<Group>>> pair = iGroupService.splitGroup(groups);

            List<Report> reports = reportMapper.getSimpleReport(simpleReport);
            Map<Long, List<TreeNodeVo>> groupId2ReportMap = new HashMap<>();
            if (reports != null && reports.size() > 0) {
                reports.forEach(r -> {
                    if (filterIds == null || !filterIds.contains(r.getId())) {
                        List<Long> gIds = r.getGroupIds();
                        TreeNodeVo vo = new TreeNodeVo(r.getId() + "", r.getName());
                        vo.setLeaf(true); // 报表只能为叶子节点
                        gIds.forEach(gId -> {
                            if (!groupId2ReportMap.containsKey(gId)) {
                                groupId2ReportMap.put(gId, new ArrayList<>());
                            }
                            groupId2ReportMap.get(gId).add(vo);
                        });
                    }
                });
            }
            // 从最深的分支开始向根节点递归
            Map<Long, List<TreeNodeVo>> preNode = new LinkedHashMap<>();
            for (int i = pair.getLeft(); i > 0; i--) {
                Map<Long, List<TreeNodeVo>> curNode = new LinkedHashMap<>();

                List<Group> tmp = pair.getRight().get(i);
                if (tmp == null) {
                    continue;
                }

                for (Group g : tmp) {
                    TreeNodeVo node = new TreeNodeVo(String.valueOf(g.getId()), g.getName(), g.getIcon());
                    node.getProps().put("group", "1");
                    boolean isBlankGroup = true;
                    if (preNode.containsKey(g.getId())) {
                        node.setChildren(preNode.get(g.getId()));
                        isBlankGroup = false;
                    }
                    if (groupId2ReportMap.containsKey(g.getId())) {
                        isBlankGroup = false;
                        node.addChildren(groupId2ReportMap.get(g.getId()));
                    }
                    if (!curNode.containsKey(g.getParentId())) {
                        curNode.put(g.getParentId(), new ArrayList<>());
                    }

                    // 空报表组不返回
                    if (!isBlankGroup) {
                        curNode.get(g.getParentId()).add(node);
                    }
                }

                preNode = curNode;
            }

            // 剔除空报表组
            preNode.values().forEach(list -> {
                for (TreeNodeVo tn : list) {
                    if (StringUtils.equals("1", tn.getProps().get("group")) && tn.getChildren().size() == 0) {
                        continue;
                    }
                    allNodes.add(tn);
                }
            });
        }

        if (StringUtils.isNotBlank(fixOption)) {
            List<TreeNodeVo> ret = new ArrayList<>();
            TreeNodeVo root;
            switch (fixOption) {
                case "NULL":
                    root = new TreeNodeVo("0", "--无--");
                    root.setChildren(allNodes);
                    ret.add(root);
                    break;
                default:
                    break;
            }
            return ret;
        }

        return allNodes;
    }

    /**
     * 获取用户拥有的报表菜单列表
     *
     * @param userId  Long 用户Id
     * @param roleIds List<Long> 角色id列表
     * @return List
     */
    @Override
    public List<MenuVo> getReportTreeOfMenu(Long userId, List<Long> roleIds) {

        List<MenuVo> allNodes = new ArrayList<>();
        // 获取所有报表组信息
        List<Group> groups = iGroupService.getAllSimpleGroup();

        if (CollectionUtils.isNotEmpty(groups)) {
            Pair<Integer, Map<Integer, List<Group>>> pair = iGroupService.splitGroup(groups);

            List<Report> reports = reportMapper.getOwnSimpleReport(userId, roleIds);
            Map<Long, List<MenuVo>> groupIdMapReport = new HashMap<>();
            for (Report r : reports) {
                Long groupId = r.getGroupIds().get(0);
                if (groupIdMapReport.containsKey(groupId)) {
                    groupIdMapReport.get(groupId).add(new MenuVo("/query/" + groupId + "/" + r.getId(), r.getName(), "line-chart"));
                } else {
                    List<MenuVo> menuVos = new ArrayList<>();
                    menuVos.add(new MenuVo("/query/" + groupId + "/" + r.getId(), r.getName(), "line-chart"));
                    groupIdMapReport.put(groupId, menuVos);
                }
            }
            for (HashMap.Entry<Long, List<MenuVo>> one : groupIdMapReport.entrySet()) {
                Group g = groupMapper.findById(one.getKey());
                MenuVo folder = new MenuVo("/query/" + one.getKey(), g.getName() + "", "folder-open");
                folder.setChildren(one.getValue());
                allNodes.add(folder);
            }
            if (1 == 1) {
                return allNodes;
            }
            //TODO temp
            MenuVo group1 = new MenuVo("/query/1", "报表组1", "folder-open");
            MenuVo group2 = new MenuVo("/query/2", "报表组2", "folder-open");
            List<MenuVo> children1 = new ArrayList<>();
            List<MenuVo> children2 = new ArrayList<>();
            for (int i = 0; i < reports.size(); i++) {
                Report r = reports.get(i);
                if (i < 1) {
                    MenuVo vo = new MenuVo("/query/1/" + r.getId(), r.getName(), "line-chart");
                    children1.add(vo);
                } else {
                    MenuVo vo = new MenuVo("/query/2/" + r.getId(), r.getName(), "line-chart");
                    children2.add(vo);
                }
            }
            group1.setChildren(children1);
            group2.setChildren(children2);
            allNodes.add(group1);
            allNodes.add(group2);
            if (1 == 1) {
                return allNodes;
            }

            Map<Long, List<MenuVo>> groupId2ReportMap = new HashMap<>();
            if (reports != null && reports.size() > 0) {
                reports.forEach(r -> {
                    List<Long> gIds = r.getGroupIds();
                    MenuVo vo = new MenuVo("/query/" + r.getId() + "/" + CodeBuilderTool.randomStr(5), r.getName(), "line-chart");
                    gIds.forEach(gId -> {
                        if (!groupId2ReportMap.containsKey(gId)) {
                            groupId2ReportMap.put(gId, new ArrayList<>());
                        }
                        groupId2ReportMap.get(gId).add(vo);
                    });
                });
            }
            // 从最深的分支开始向根节点递归
            Map<Long, List<MenuVo>> preNode = new LinkedHashMap<>();
            for (int i = pair.getLeft(); i > 0; i--) {
                Map<Long, List<MenuVo>> curNode = new LinkedHashMap<>();

                List<Group> tmp = pair.getRight().get(i);
                if (tmp == null) {
                    continue;
                }

                for (Group g : tmp) {
                    MenuVo node = new MenuVo("/group/" + i + "/" + g.getId(), g.getName(), "folder-open");
                    node.addProp("group", "1");
                    boolean isBlankGroup = true;
                    if (preNode.containsKey(g.getId())) {
                        node.setChildren(preNode.get(g.getId()));
                        isBlankGroup = false;
                    }
                    if (groupId2ReportMap.containsKey(g.getId())) {
                        isBlankGroup = false;
                        node.addChildren(groupId2ReportMap.get(g.getId()));
                    }
                    if (!curNode.containsKey(g.getParentId())) {
                        curNode.put(g.getParentId(), new ArrayList<>());
                    }

                    // 空报表组不返回
                    if (!isBlankGroup) {
                        curNode.get(g.getParentId()).add(node);
                    }
                }

                preNode = curNode;
            }

            // 剔除空报表组
            preNode.values().forEach(list -> {
                for (MenuVo tn : list) {
                    if (StringUtils.equals("1", tn.getProp("group")) && tn.getChildren().size() == 0) {
                        continue;
                    }
                    allNodes.add(tn);
                }
            });

        }
        return allNodes;
    }

    /**
     * 获取报表查询参数信息
     *
     * @param reportId Long
     * @return List
     */
    @Override
    public List<QueryArg> getReportQueryArgs(Long reportId) {
        List<QueryArg> args = new ArrayList<>();

        List<QueryField> fields = getQueryFields(reportId);
        if (fields == null || fields.isEmpty()) {
            return args;
        }

        Map<String, QueryArg> map = new LinkedHashMap<>(); // 保证顺序
        Map<String, QueryField> lovFields = new LinkedHashMap<>();

        // 初次解析, 默认值
        for (QueryField field : fields) {
            // 过滤内部字段
            if (QueryFieldType.contains(field.getType(), QueryFieldType.INNER)) {
                continue;
            }

            QueryArg arg = new QueryArg();
            arg.setLabel(field.getShowName());        // 显示名称
            arg.setName(field.getQueryName());        // 查询字段名
            arg.setMustFillIn(field.getMustFillIn()); // 是否必填
            arg.setDataType(field.getDataType());     // 数据类型

            // 构建组件
            BaseComponent component = ComponentFactory.build(field);
            arg.setComponent(component);

            boolean isLov = QueryFieldType.contains(field.getType(), QueryFieldType.LOV);
            if (isLov) {
                lovFields.put(field.getQueryName(), field);
            }

            map.put(field.getQueryName(), arg);
        }

        //  获取lov的信息值
        int deep = 1;
        while (lovFields.size() > 0) {
            if (QUERY_FIELD_UPLINK_MAX < deep) {
                log.error("报表Id: {}, 查询参数级联超过最大允许值: {}", reportId, QUERY_FIELD_UPLINK_MAX);
                break; // 如果超过最大允许深度,则直接跳出;
            }

            Map<String, QueryField> children = new HashMap<>();
            for (String name : lovFields.keySet()) {
                QueryArg arg = map.get(name);

                // lov、需要查询数据源的组件
                if (arg.getComponent() instanceof SelectComponent) {
                    SelectComponent component = (SelectComponent) arg.getComponent();

                    boolean doQuery = true;

                    List<String> dependOns = component.getDependOn();
                    Map<String, Object> params = new HashMap<>();
                    for (String key : dependOns) {
                        if (lovFields.containsKey(key)) {
                            doQuery = false;
                            children.put(name, lovFields.get(name));
                            break;
                        }
                        QueryArg dependOnArg = map.get(key);
                        params.put(key, dependOnArg.getComponent().getDefaultValue()); // 获取默认值
                    }
                    // 该组件还存在上级lov需要处理
                    if (!doQuery) {
                        break;
                    }

//                    getIdByCode()
//                    iReportDataQueryService.queryByCode()
                }
            }
            deep++;
        }


        // 添加所有
        args.addAll(map.values());

        return args;
    }

    /**
     * 根据报表id复制一份新的报表
     *
     * @param oldReportId Long 原先的报表id
     */
    @Transactional
    @Override
    public int copyReport(Long oldReportId) {
        Report oldReport = reportMapper.findById(oldReportId);
        Report tmp = new Report();
        BeanUtils.copyProperties(oldReport, tmp);
        tmp.setId(null);
        tmp.setAutoCreatedCode(0);
        String newReportCode = CodeBuilderTool.randomStr(CODE_LEN);
        tmp.setCode(newReportCode);
        tmp.setName(StringUtils.substringBefore(oldReport.getName(), "_copy_") + "_copy_" + newReportCode);
        tmp.setOwner(null);
        tmp.setCreatedBy(null);
        tmp.setModifiedBy(null);
        addReport(tmp, reportRlGroupMapper.getGroupIdsByReportId(oldReportId));
        Report newReport = reportMapper.findByCode(newReportCode);

        saveQueryFields(newReport.getId(), getQueryFields(oldReportId), false);
        if (oldReport.getDetailSqlId() != null) {
            ReportSql reportSql = getSqlInfoById(oldReport.getDetailSqlId());
            reportSql.setId(null);
            saveReportSql(newReport.getId(), reportSql, false);
        }
        saveReportColumns(newReport.getId(), getReportColumns(oldReportId), false);
        return 1;
    }

    @Override
    public List<Report> getReportCodeAndName() {
        return reportMapper.getReportCodeAndName();
    }

    /**
     * 获取报表数量
     *
     * @return int
     */
    @Override
    public int getReportSize() {
        return reportMapper.getTotalReportSize();
    }

    @Override
    public Report getReportByCode(String reportCode) {
        return reportMapper.findByCode(reportCode);
    }

    @Override
    public ReportSql getReportSqlById(Long sqlId) {
        return reportSqlMapper.findById(sqlId);
    }

    @Override
    public List<ReportColumn> listColumnByReportId(Long reportId) {
        return reportColumnMapper.getByReportId(reportId);
    }

    @Override
    public List<QueryField> listQueryFieldByReportId(Long reportId) {
        return queryFieldMapper.getByReportId(reportId);
    }

}
